<?php

    function getNiMatrix($matrix) {
        /*定义扩展矩阵*/
        for($i=0; $i<count($matrix); $i++) {
            for ($j=0; $j<count($matrix)*2; $j++) {
                $expandMatrix[$i][$j] = 0;
            }
        }
        for($i=0; $i<count($matrix); $i++) {
            for ($j=0; $j<count($matrix); $j++) {
                /*定义得到的逆矩阵*/
                $newMatrix[$i][$j] = 0;
            }
        }
        /*初始化扩展矩阵*/
        $expandMatrix = initExpandMatrix($matrix, $expandMatrix);
        /*调整扩展矩阵，若某一列全为0，则行列式的值等于0，不存在逆矩阵*/
	    $canAdjust = adjustMatrix($expandMatrix);
        if (false == $canAdjust)//如果不存在逆矩阵，返回NULL
            return null;
        /*计算扩展矩阵*/
        $expandMatrix = calculateExpandMatrix($expandMatrix);
        /*用计算过的扩展矩阵取后面的N*N矩阵，为所求*/
        $newMatrix = getNewMatrix($expandMatrix, $newMatrix);
        return $newMatrix;
    }

    /*初始化扩展矩阵*/
    function initExpandMatrix($initMatrix, $expandMatrix) {
	    for ($i = 0; $i < count($initMatrix) * 2; $i++) {
            for ($j = 0; $j < count($initMatrix[$i])* 2; $j++) {
                if ($j < count($initMatrix)) {//左边的N*N矩阵原样赋值
                    if($i >= count($initMatrix)) {
                        $expandMatrix[$i][$j] = 0;
                    } else {
                        $expandMatrix[$i][$j] = $initMatrix[$i][$j];
                   }
                } else {    //右边N*N赋值为单位矩阵
                    $expandMatrix[$i][$j] = (($i+count($initMatrix))==$j)? 1:0;
                } 
            }
        }
        return $expandMatrix;
    }

    /*调整扩展矩阵，若某一列全为0，则行列式的值等于0，不存在逆矩阵*/
    function adjustMatrix($expandMatrix) {
        for ($i = 0; $i < count($expandMatrix); $i++) {
            if ($expandMatrix[$i][$i] == 0) {//如果某行对角线数值为0
                /*搜索该列其他不为0的行，如果都为0，则返回false*/
                for ($j = 0; $j < count($expandMatrix); $j++) {
                    if ($expandMatrix[$j][$i] != 0) {//如果有不为0的行，交换这两行
                        $temp = $expandMatrix[$i];
                        $expandMatrix[$i] = $expandMatrix[$j];
                        $expandMatrix[$j] = $temp;
                        break;
                    }
                }
                if ($j >= count($expandMatrix)) {//没有不为0的行
                    return false;
                }
            }
        }
        return true;
    }
    /*计算扩展矩阵*/
    function calculateExpandMatrix($expandMatrix) {
        for ($i = 0; $i < count($expandMatrix); $i++) {
            $firstElement = $expandMatrix[$i][$i];
            for ($j = 0; $j < count($expandMatrix[$i]); $j++) {
                $expandMatrix[$i][$j] /= $firstElement;//将该行所有元素除以首元素
            }
            /*把其他行再该列的数值都化为0*/
            for ($m = 0; $m < count($expandMatrix); $m++) {
                if ($m == $i) {//遇到自己的行跳过
                    continue;
                }
                $beishu = $expandMatrix[$m][$i];
                for ($n = 0; $n < count($expandMatrix[$i]); $n++) {
                    $expandMatrix[$m][$n] -= $expandMatrix[$i][$n] * $beishu;
                }
            }
        }
        return $expandMatrix;
    }
    /*用计算过的扩展矩阵取后面的N*N矩阵，为所求*/
    function getNewMatrix($expandMatrix, $newMatrix) {
        for ($i = 0; $i < count($expandMatrix); $i++) {
            for ($j = 0; $j < count($expandMatrix[$i]); $j++) {
                if ($j >= count($expandMatrix)) {
                    $newMatrix[$i][$j - count($expandMatrix)] = $expandMatrix[$i][$j];
                }
            }
        }
        return $newMatrix;
    }

    /*打印矩阵*/
    function printMatrix($matrix){

    }
    /*矩阵做乘法，验证结果*/
    function getProductMatrix( $initMatrix, $newMatrix) {
        $len = count($initMatrix);
        $productMatrix = [];
        for($i = 0; $i < $len; $i++){
            for($j = 0; $j < $len; $j++) {
                for ($k = 0; $k < $len; $k++) {
                    $productMatrix[$i][$j] += $initMatrix[$i][$k] * $newMatrix[$k][$j];
                }
            }
        }
        return $productMatrix;
    }

    //$initMatrix = [[1, 2, -1 ], [3, 4, -2 ], [5, -4, 1 ]];
//    $initMatrix =[[1,1,-1],[0,1,1],[0,0,1]];
    //$initMatrix = [[1, 3, 4, 3],[0, 2, 3, 0],[1, 1, 1, 3],[0, 0, 3, 0]];
//    $returnData = getNiMatrix($initMatrix);
//    var_dump($returnData);
?>
